#define  _GNU_SOURCE
#include <bmp.h>
#include <lcd.h>

extern int fd;
extern int *plcd;
int n=4;      //百叶窗区块数


//显示一张bmp图片
int show_bmp( int x0, int y0, char * filename )
{
    //1.打开图片文件
    int bmp=open(filename,O_RDWR);
    if(bmp==-1)
    {
        perror("open .bmp fail");
        return 0;
    }
    //2.读取图片的数据 
    
    //读取 宽度、高度、色深 
    int width = 0;
    lseek( bmp, 0x12, SEEK_SET );
    read( bmp, &width, 4 );

    int height = 0;
    lseek( bmp, 0x16, SEEK_SET );
    read( bmp, &height, 4 );

    short depth = 0;
    lseek( bmp, 0x1C, SEEK_SET );
    read( bmp, &depth, 2 );
    //读取像素点的颜色数据

    int line_size = 0;      //一行实际的字节数
    int laizi = 0;          //填充的字节数 

    laizi = 4 - ( abs(width)*(depth/8) ) % 4 ;
    if( laizi == 4 )
    {
        laizi = 0;
    }

    //一行实际的字节数 = 有效的字节数 + 填充的字节数
    line_size = abs(width)*(depth/8) + laizi;

    //一次性把整个图像的像素点数据 全部读取处理 
    unsigned char buf[ abs(height) * line_size ];
    lseek( bmp, 0x36, SEEK_SET );
    read( bmp, buf, abs(height) * line_size );

    //3.显示 
    int i,j;
    int color;
    unsigned char a,r,g,b;
    int num = 0;

    for( j=0; j<abs(height); j++ )
    {
        for( i=0; i<abs(width); i++ )
        {
            //合成像素点的颜色值
            b = buf[num++];
            g = buf[num++];
            r = buf[num++];
            if( depth == 32 )
            {
                a = buf[num++];
            }
            else
            {
                a = 0;
            }
            color = (a<<24) | (r<<16) | (g<<8) | b;

            //画点 
            {
                display_point(  (width>0?i+x0:abs(width)-1-i)+x0 , (height>0?abs(height)-1-j:j)+y0 ,color );
            }
        }

        num = num + laizi;      //跳过无效的填充数据
    }
    //4.关闭图片 
    close(bmp);

}

int get_bmp_name( char * path , DList * list )
{
    //1.打开目录 
    DIR *dir=opendir(path);
    if( dir == NULL )
    {
        perror("opendir error ");
        return -1;
    }
    //2.读取目录项
    struct dirent *d;
    while( d = readdir( dir ) )
    {       
        if( strcmp( d->d_name , "." ) == 0 || strcmp( d->d_name , ".." ) == 0 )
        {
            continue;
        }
        
        //3.合成路径名 ---> “路径/文件名”
        char s[128]={0};
        strcpy( s, path ); 
        if(s[strlen(s)-1]!='/')
            s[ strlen(s) ] = '/';
        strcat(s,d->d_name);

        //4.判断后缀名是否为.bmp 
            
        if( d->d_type == DT_REG )   //普通文件 
        {
            if( strcmp(s+strlen(s)-4,".bmp")==0 )
            {
                //5.把图片的名字 添加到链表中 
                DNode * pnew = (DNode *)malloc( sizeof(DNode) );
                strcpy( pnew->data, s );
                pnew->next = NULL;
                pnew->prev = NULL;
                insert_node(list,pnew);
            }
        }
        
    }

    //6.关闭目录 
    closedir(dir);
}

int Circle_show_bmp( char * path )
{
    //创建一个双向链表 
    DList * list = (DList *)malloc( sizeof(DList) );
    list->first = NULL;
    list->last = NULL;
    list->num = 0;
    //搜索指定目录下的所有的bmp图片，并保存到链表中
    get_bmp_name( path, list );

    //首位相连 ---> 循环链表
    if( list->num != 0 )        //链表不为空
    {
        list->last->next = list->first;
        list->first->prev = list->last;
    }

    DNode * p=list->first;

    while( 1 )
    {
        //显示bmp图片
        show_bmp(100,100,p->data);
        printf("%s\n",p->data);
        //延时 
        //sleep(1);
        usleep(100000);
        p = p->next;
    }

    //销毁链表 
    destroy_list(list);
}

int Touch_change_bmp( char * path )
{
    //创建一个双向链表 
    DList * list = (DList *)malloc( sizeof(DList) );
    list->first = NULL;
    list->last = NULL;
    list->num = 0;
    //搜索指定目录下的所有的bmp图片，并保存到链表中
    get_bmp_name( path, list );

    //首位相连 ---> 循环链表
    if( list->num != 0 )        //链表不为空
    {
        list->last->next = list->first;
        list->first->prev = list->last;
    }

    DNode * p=list->first;

    while( 1 )
    {
        //显示bmp图片
        int err=show_bmp(0,0,p->data);
        if(err==0)
            break;
        printf("%s\n",p->data);
        if(get_direction()==1||get_direction()==3)
        {
            p=p->prev;
        }
        else
        {
            p = p->next;
        }
        
    }

    //销毁链表 
    destroy_list(list);
}


int Bai_ye_chuang( int x0, int y0, char * filename )
{
    //1.打开图片文件
    int bmp=open(filename,O_RDWR);
    if(bmp==-1)
    {
        perror("open .bmp fail");
        return 0;
    }
    //2.读取图片的数据 
    
    //读取 宽度、高度、色深 
    int width = 0;
    lseek( bmp, 0x12, SEEK_SET );
    read( bmp, &width, 4 );

    int height = 0;
    lseek( bmp, 0x16, SEEK_SET );
    read( bmp, &height, 4 );

    short depth = 0;
    lseek( bmp, 0x1C, SEEK_SET );
    read( bmp, &depth, 2 );
    //读取像素点的颜色数据

    int line_size = 0;      //一行实际的字节数
    int laizi = 0;          //填充的字节数 

    laizi = 4 - ( abs(width)*(depth/8) ) % 4 ;
    if( laizi == 4 )
    {
        laizi = 0;
    }

    //一行实际的字节数 = 有效的字节数 + 填充的字节数
    line_size = abs(width)*(depth/8) + laizi;

    //一次性把整个图像的像素点数据 全部读取处理 
    unsigned char buf[ abs(height) * line_size ];
    lseek( bmp, 0x36, SEEK_SET );
    read( bmp, buf, abs(height) * line_size );

    //3.显示 
    int color;
    unsigned char a,r,g,b;
    int block_row;   //block_row:每个区块的行数  
    struct Block block[100];
    int change=0,flag=0;


    if(600%n!=0)
    {
        printf("input error...\n\n");
        return 0;
    }
    else
    {

        block_row=600/n;

        for(int i=0;i<n;i++)
        {
            block[i].num=( abs(width)*(depth/8) +laizi)*block_row*i;      //初始化每个区块第一个像素点在buf中的下标num
            block[i].col=-1;              //初始化每个区块列坐标
            block[i].row=block_row*i;     //初始化每个区块行坐标
            block[i].output_row=0;        //初始化每个区块已输出的行数
        }

        while(1)       //每次循环显示0~1个像素点
        {
            
            if( (flag==0 && change%2 == 0 )|| (flag==1 && block[change].output_row<=block_row ) )
            {
                //合成像素点的颜色值
                b = buf[block[change].num++];
                g = buf[block[change].num++];
                r = buf[block[change].num++];
                if( depth == 32 )
                {
                    a = buf[block[change].num++];
                }
                else
                {
                    a = 0;
                }
                color = (a<<24) | (r<<16) | (g<<8) | b;

                //画点 
                block[change].col=(block[change].col+1)%abs(width);
                display_point(  (width>0 ? (block[change].col)+x0 : abs(width)-1-(block[change].col))+x0 , (height>0 ? abs(height)-(block[change].row) : (block[change].row))+y0 ,color );
                
                if(block[0].output_row==block_row/2)
                {
                    flag=1;
                }
            }

            if(block[change].col==0)   //当前区块已显示一行像素点
            {   
                block[change].output_row++;

                if(block[change].output_row <= block_row)
                {
                    block[change].row=block[change].row+1;
                }
                    
                block[change].num =block[change].num + laizi;      //跳过无效的填充数据
                if(n%2)
                {
                        if(block[n-1].col==0 && flag==0 || block[n-2].col==0 && flag==1)   //最后一个显示的区块已显示一行像素点
                        {
                            usleep(10000);
                        }
                }
                else
                {
                    if(block[n-2].col==0 && flag==0 || block[n-1].col==0 && flag==1)    //最后一个显示的区块已显示一行像素点
                        {
                            usleep(10000);
                        }
                }
                
            }
            change=(change+1)%n;      //切换当前区块
            
            if(block[n-1].output_row>block_row && block[n-2].output_row>block_row)
                {
                    break;
                }

        }
       
    }
    //4.关闭图片 
    close(bmp);
    return 1;
}
